<?php
namespace app\common\service;

use Simps\MQTT\Client;
use Simps\MQTT\Config\ClientConfig;
use Simps\MQTT\Exception\ConnectException;

class MqttService
{
    protected $client;
    protected $config;
    protected $isConnected = false; // 手动跟踪连接状态

    public function __construct()
    {
        $config = Config::get('mqtt.');
        // MQTT服务器配置（根据实际情况修改）
        if (empty($config['client_id']) || strpos($config['client_id'], 'uniqid()') !== false) {
            $config['client_id'] = 'tp_client_' . uniqid();
        }
        $this->config  = $config;
    }

    /**
     * 检查是否已连接
     */
    public function isConnected(): bool
    {
        return $this->isConnected;
    }

    /**
     * 连接MQTT服务
     */
    public function connect(): bool
    {
        // 如果已连接则直接返回
        if ($this->isConnected) {
            return true;
        }

        try {
            $clientConfig = new ClientConfig();
            $clientConfig->setUserName($this->config['username'])
                         ->setPassword($this->config['password'])
                         ->setKeepAlive($this->config['keepalive']);

            $this->client = new Client($this->config['host'], $this->config['port'], $clientConfig,2);
            $this->client->connect();
            $this->isConnected = true; // 标记为已连接
            return true;
        } catch (ConnectException $e) {
            $this->isConnected = false;
            \think\facade\Log::error('MQTT连接失败: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * 发送MQTT消息
     */
    public function publish(string $topic, string $message, int $qos = 0): bool
    {
        // 先检查连接状态
        if (!$this->isConnected && !$this->connect()) {
            return false;
        }

        try {
            $this->client->publish($topic, $message, $qos);
            return true;
        } catch (\Exception $e) {
            $this->isConnected = false; // 发送失败时标记为断开
            \think\facade\Log::error('MQTT发送失败: ' . $e->getMessage());
            
            // 尝试自动重连一次
            if ($this->connect()) {
                try {
                    $this->client->publish($topic, $message, $qos);
                    return true;
                } catch (\Exception $e) {
                    $this->isConnected = false;
                    \think\facade\Log::error('MQTT重试发送失败: ' . $e->getMessage());
                }
            }
            return false;
        }
    }

    /**
     * 断开连接
     */
    public function disconnect(): void
    {
        if ($this->isConnected && $this->client) {
            try {
                $this->client->close();
            } catch (\Exception $e) {
                \think\facade\Log::error('MQTT断开连接异常: ' . $e->getMessage());
            }
            $this->isConnected = false; // 确保状态更新
        }
    }

    public function __destruct()
    {
        $this->disconnect();
    }
}